package com.wk.code.wkserver.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wk.code.wkserver.constant.Constant;
import com.wk.code.wkserver.constant.EmailConstant;
import com.wk.code.wkserver.constant.NumberConstant;
import com.wk.code.wkserver.constant.enums.*;
import com.wk.code.wkserver.entity.*;
import com.wk.code.wkserver.exception.BizException;
import com.wk.code.wkserver.manager.AsyncTaskManager;
import com.wk.code.wkserver.mapper.DemandMapper;
import com.wk.code.wkserver.request.admin.AdminDemandRequest;
import com.wk.code.wkserver.request.app.DemandPageRequest;
import com.wk.code.wkserver.request.app.DemandRequest;
import com.wk.code.wkserver.request.app.DemandVerifyRequest;
import com.wk.code.wkserver.request.base.BasePageRequest;
import com.wk.code.wkserver.response.admin.AdminVerifyRecordResponse;
import com.wk.code.wkserver.response.admin.DemandOrderResponse;
import com.wk.code.wkserver.response.admin.DemandResponse;
import com.wk.code.wkserver.response.app.AppDemandResponse;
import com.wk.code.wkserver.response.app.UserInfoDetailResponse;
import com.wk.code.wkserver.response.base.PageInfo;
import com.wk.code.wkserver.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wk.code.wkserver.utils.DateUtils;
import com.wk.code.wkserver.utils.IdWorkUtils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wq
 * @since 2021-08-15
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DemandServiceImpl extends ServiceImpl<DemandMapper, Demand> implements IDemandService {


    @Resource
    private IUserService userService;

    @Resource
    private ITechTypeService techTypeService;

    @Resource
    private IUserInfoService userInfoService;

    @Resource
    private IAdminVerifyRecordService adminVerifyRecordService;

    @Resource
    private IMailService mailService;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private IEstimateAmountService estimateAmountService;

    @Resource
    private IOrderTakingRecordService orderTakingRecordService;

    @Resource
    private IDemandOrderService demandOrderService;

    @Resource
    private AsyncTaskManager asyncTaskManager;

    @Resource
    private IUserAccountService userAccountService;

    @Resource
    private IUserAccountRecordService userAccountRecordService;

    @Resource
    private ISysConfigService sysConfigService;

    @Resource
    private RedissonClient redissonClient;


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void publish(Integer userId, DemandRequest request) {
        User user = userService.selectById(userId);
        if (Objects.isNull(user)) {
            throw new BizException("你还未登录");
        }

        if (StringUtils.isEmpty(request.getDescription())) {
            throw new BizException("请输入需求描述");
        }
        if (StringUtils.isEmpty(request.getTitle())) {
            throw new BizException("请输入需求标题");
        }
        if (Objects.isNull(request.getEstimateAmountId())) {
            throw new BizException("请选择预算");
        }
        //第一次发布创建用户信息
        createUserInfoFirstPublish(request, user);
        if (!CollectionUtils.isEmpty(request.getImages())) {
            if (request.getImages().size() > NumberConstant.THREE) {
                throw new BizException("最多上传3张图片哦");
            }
        }
        //判断是否是客服发布
        if (user.getRegisterType().equals(UserTypeEnum.CUSTOMER.getCode())) {
            Demand demand = new Demand();
            if (StringUtils.isNotEmpty(request.getHopeFinishTime())) {
                demand.setHopeFinishTime(request.getHopeFinishTime());
            }
            demand.setDescription(request.getDescription());
            demand.setEstimateAmountId(request.getEstimateAmountId());
            demand.setUserId(userId);
            demand.setViewCount(NumberConstant.ZERO);
            demand.setTitle(request.getTitle());
            //设置系统用户ID
            SysUser sysUser = sysUserService.selectUserId(user.getMobile());
            if (Objects.nonNull(sysUser)) {
                demand.setSysUserId(sysUser.getId());
            }
            if (!CollectionUtils.isEmpty(request.getImages())) {
                demand.setImages(JSONObject.toJSONString(request.getImages()));
            }
            if (Objects.nonNull(request.getTechTypeId())) {
                //需求类型
                demand.setTechTypeId(request.getTechTypeId());
            }
            demand.setStatus(DemandStatusEnum.VERIFY_PASS.getCode());
            save(demand);
            //todo 通知相关技术接单
        } else {
            Demand demand = new Demand();
            if (StringUtils.isNotEmpty(request.getHopeFinishTime())) {
                demand.setHopeFinishTime(request.getHopeFinishTime());
            }
            demand.setDescription(request.getDescription());
            demand.setEstimateAmountId(request.getEstimateAmountId());
            demand.setUserId(userId);
            demand.setViewCount(NumberConstant.ZERO);
            demand.setTitle(request.getTitle());
            //随机分配一个在线客服 并发布通知给客服让客服尽快审核
            SysUser sysUser = sysUserService.randCustomer();
            if (Objects.nonNull(sysUser)) {
                demand.setSysUserId(sysUser.getId());
                //通知客服审核
                notifyCustomerVerify(sysUser, user, request.getTitle());
            }
            if (!CollectionUtils.isEmpty(request.getImages())) {
                demand.setImages(JSONObject.toJSONString(request.getImages()));
            }
            if (Objects.nonNull(request.getTechTypeId())) {
                //需求类型
                demand.setTechTypeId(request.getTechTypeId());
            }
            demand.setStatus(DemandStatusEnum.TO_VERIFY.getCode());
            save(demand);
        }

    }

    private void createUserInfoFirstPublish(DemandRequest request, User user) {
        if (user.getIsAuth().equals(NumberConstant.ONE) && user.getRegisterType().equals(UserTypeEnum.DEMAND_USER.getCode())) {
            if (StringUtils.isEmpty(request.getUserInfoRequest().getQqAccount())) {
                throw new BizException("请输入qq号");
            }
            if (StringUtils.isEmpty(request.getUserInfoRequest().getEmail())) {
                throw new BizException("请输入邮箱");
            }
            if (StringUtils.isEmpty(request.getUserInfoRequest().getWechatAccount())) {
                throw new BizException("请输入微信号");
            }
            userInfoService.updateUserInfo(user.getId(), request.getUserInfoRequest());
        }
    }

    /**
     * 通知客服审核
     *
     * @param sysUser 系统用户
     * @param user    用户
     * @param title   title
     */
    private void notifyCustomerVerify(SysUser sysUser, User user, String title) {
        asyncTaskManager.execute(() -> mailService.sendMail(sysUser.getEmail(),
                String.format(Constant.DEMAND_PUBLISH_CONTENT, user.getNickname(), title)));
    }

    @Override
    public List<AppDemandResponse> acquire(DemandPageRequest request) {
        //更新访问时间
        if (Objects.nonNull(request.getUserId())) {
            userService.update(null, new LambdaUpdateWrapper<User>().eq(User::getId,
                    request.getUserId()).set(User::getLastVisitTime, new Date()));
        }
        IPage<Demand> page = new Page<>(request.getPageNumber(), request.getPageSize());
        LambdaQueryWrapper<Demand> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Demand::getStatus, Arrays.asList(3, 4, 5, 6));
        wrapper.orderByDesc(Demand::getCreateTime);
        wrapper.orderByAsc(Demand::getStatus);
        IPage<Demand> pages = baseMapper.selectPage(page, wrapper);
        if (!CollectionUtils.isEmpty(pages.getRecords())) {
            return pages.getRecords().stream().
                    map(x -> getListDemandResponse(null, x)).
                    collect(Collectors.toList());
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void verifyDemand(Integer sysUserId, DemandVerifyRequest request) {
        Demand demand = getById(request.getDemandId());
        //审核通过
        if (request.getVerifyStatus().equals(AdminVerifyStatusEnum.VERIFY_PASS.getCode())) {
            if (Objects.nonNull(demand)) {
                //修改状态
                demand.setStatus(DemandStatusEnum.VERIFY_PASS.getCode());
                updateById(demand);
                //增加审核记录
                createVerifyRecord(sysUserId, request);
                //发送邮件
                //sendDemandEmail(demand.getUserId(), AdminVerifyStatusEnum.VERIFY_PASS.getCode(), null);
            }
        } else {
            //不通过
            demand.setStatus(DemandStatusEnum.VERIFY_REJECT.getCode());
            updateById(demand);
            //增加审核记录
            createVerifyRecord(sysUserId, request);
            //发送邮件
            //sendDemandEmail(demand.getUserId(), AdminVerifyStatusEnum.VERIFY_REJECT.getCode(), request.getRemark());
        }
    }


    /**
     * 发送邮件
     *
     * @param userId       用户ID
     * @param verifyStatus 审核状态
     */
    private void sendDemandEmail(Integer userId, Integer verifyStatus, String remark) {
        UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, userId));
        if (Objects.nonNull(userInfo)) {
            if (verifyStatus.equals(AdminVerifyStatusEnum.VERIFY_PASS.getCode())) {
                mailService.sendMail(userInfo.getEmail(), String.format(Constant.DEMAND_VERIFY_PASS, userInfo.getEmail()));
            } else {
                mailService.sendMail(userInfo.getEmail(), String.format(Constant.DEMAND_VERIFY_REJECT, userInfo.getEmail(), remark));
            }
        }
    }

    /**
     * 增加审核记录
     *
     * @param request request
     */
    private void createVerifyRecord(Integer sysUserId, DemandVerifyRequest request) {
        adminVerifyRecordService.save(request.getDemandId(), sysUserId,
                request.getVerifyStatus(), request.getRemark(), AdminVerifyTypeEnum.DEMAND_VERIFY.getCode());
    }


    @Override
    public PageInfo<DemandResponse> page(Integer sysUserId, AdminDemandRequest request) {
        IPage<Demand> page = new Page<>(request.getPageNumber(), request.getPageSize());
        //查询该系统用户的权限
        String roleName = sysUserService.selectUserRole(sysUserId);
        if (roleName.equals(SysUserRoleEnum.CUSTOMER.getValue())) {
            request.setUserRoleType(SysUserRoleEnum.CUSTOMER.getCode());
        }
        request.setSysUserId(sysUserId);
        IPage<DemandResponse> list = baseMapper.pageList(page, request);
        if (!CollectionUtils.isEmpty(list.getRecords())) {
            List<Integer> sysUserIds = list.getRecords().stream().map(DemandResponse::getSysUserId).collect(Collectors.toList());
            Map<Integer, SysUser> map = sysUserService.listByIds(sysUserIds).parallelStream().
                    collect(Collectors.toMap(SysUser::getId, Function.identity()));
            for (DemandResponse record : list.getRecords()) {
                SysUser sysUser = map.get(record.getSysUserId());
                if (Objects.nonNull(sysUser)) {
                    record.setCustomerName(sysUser.getNickname());
                }
                //查询下单金额
                DemandOrder demandOrder = demandOrderService.selectByDemandId(record.getId());
                if (Objects.nonNull(demandOrder)) {
                    record.setOrderAmount(demandOrder.getOrderAmount());
                }
            }
            return new PageInfo<>(page.getTotal(), list.getRecords());
        }
        return null;
    }

    @Override
    public Integer acquireDemandCount(Integer userId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<Demand>().eq(Demand::getUserId, userId));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void applyOrderTaker(Integer demandId, Integer techUserId) {
        //申请接单
        User user = userService.selectById(techUserId);
        if (Objects.nonNull(user)) {
            if (user.getStatus().equals(UserStatusEnum.PROHIBIT.getCode())) {
                throw new BizException("账号已被封禁,请联系客服");
            }
        }
        if (!user.getRegisterType().equals(UserTypeEnum.TECHNOLOGY_USER.getCode())) {
            throw new BizException("你还未认证成功技术员,不能接单");
        }
        Demand demand = baseMapper.selectById(demandId);
        if (Objects.isNull(demand)) {
            throw new BizException("该需求已被删除");
        }
        if (techUserId.equals(demand.getUserId())) {
            throw new BizException("自己的需求不能接哦");
        }
        if (!demand.getStatus().equals(DemandStatusEnum.VERIFY_PASS.getCode())) {
            throw new BizException("该需求状态不能申请接单");
        }
        if (demand.getStatus().equals(DemandStatusEnum.ALREADY_ORDERED.getCode())) {
            throw new BizException("该需求已被其他技术员接啦");
        }
        //查询该需求是否是取消后在申请的
        OrderTakingRecord orderTakingRecord = orderTakingRecordService.selectOrderTakingRecord(techUserId, demandId);
        if (Objects.nonNull(orderTakingRecord)) {
            throw new BizException("该需求你不能再次接单");
        }
        //修改该需求状态
        demand.setStatus(DemandStatusEnum.ALREADY_ORDERED.getCode());
        //设置该需求的接单用户
        demand.setTechUserId(techUserId);
        updateById(demand);
        //保存该用户的接单记录
        orderTakingRecordService.save(demandId, techUserId);
        //通知客服xxx技术员申请接单 线下拉群
        asyncTaskManager.execute(() -> notifyCustomerOrderTaking(demand));
    }

    @Override
    public Demand selectOrderDemand(Integer demandId) {
        return baseMapper.selectById(demandId);
    }

    @Override
    public List<AppDemandResponse> mineDemand(Integer userId) {
        LambdaQueryWrapper<Demand> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Demand::getCreateTime);
        wrapper.eq(Demand::getUserId, userId);
        List<Demand> records = baseMapper.selectList(wrapper);
        if (!CollectionUtils.isEmpty(records)) {
            return records.stream().map(x -> {
                AppDemandResponse response = new AppDemandResponse();
                BeanUtils.copyProperties(x, response);
                //需求号码生成规则 W-000001
                response.setDemandNo(Constant.DEMAND_PREFIX + IdWorkUtils.getDemandNo(String.valueOf(x.getId())));
                response.setPublishTime(DateUtils.localDateTime2DateStr(DateUtils.YYYY_MM_DD_HH_MM_SS, x.getCreateTime()));
                //设置预算区间
                response.setEstimateAmount(estimateAmountService.getById(x.getEstimateAmountId()).getPrice());
                if (StringUtils.isNotEmpty(x.getImages())) {
                    response.setImage(JSONObject.parseArray(x.getImages(), String.class));
                }
                if (!DemandStatusEnum.TO_VERIFY.getCode().equals(x.getStatus())) {
                    //查询审核备注
                    List<AdminVerifyRecordResponse> verifyRecordResponses = adminVerifyRecordService.selectList(x.getId(), AdminVerifyTypeEnum.DEMAND_VERIFY.getCode());
                    if (!CollectionUtils.isEmpty(verifyRecordResponses)) {
                        String remark = verifyRecordResponses.get(0).getRemark();
                        response.setRemark(remark);
                    }
                }
                response.setStatus(x.getStatus());
                return response;
            }).collect(Collectors.toList());
        }
        return null;
    }

    @Override
    public Integer selectUserDemandCount(Integer userId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<Demand>().
                eq(Demand::getUserId, userId));
    }

    @Override
    public void deleteDemand(Integer demandId, Integer userId) {
        Demand demand = baseMapper.selectById(demandId);
        if (demand.getStatus().equals(DemandStatusEnum.ALREADY_ORDERED.getCode()) || demand.getStatus().equals(DemandStatusEnum.PROCESSING.getCode())) {
            throw new BizException("该需求已接单或者进行中不能删除");
        }
        baseMapper.delete(new LambdaQueryWrapper<Demand>().eq(Demand::getId, demandId).eq(Demand::getUserId, userId));
    }

    @Override
    public List<Demand> selectDemandList(ArrayList<Integer> demandNoTakings) {
        if (CollectionUtils.isEmpty(demandNoTakings)) {
            return new ArrayList<>();
        }
        return baseMapper.selectList(new LambdaQueryWrapper<Demand>().in(Demand::getId, demandNoTakings).orderByDesc(Demand::getCreateTime));
    }

    @Override
    public void updateDemandCancel(Integer demandId) {
        //查询该需求是否是已接单的需求
        Demand demand = baseMapper.selectById(demandId);
        if (Objects.nonNull(demand)) {
            if (demand.getStatus().equals(DemandStatusEnum.ALREADY_ORDERED.getCode())) {
                //修改需求状态 并设置接单技术为空
                demand.setStatus(DemandStatusEnum.VERIFY_PASS.getCode());
                demand.setTechUserId(null);
                updateById(demand);
            }
        }
    }

    @Override
    public void deleteDemand(Integer demandId) {
        //待接单的才能删除
        Demand demand = baseMapper.selectById(demandId);
        if (Objects.nonNull(demand)) {
            if (DemandStatusEnum.VERIFY_PASS.getCode().equals(demand.getStatus())) {
                baseMapper.deleteById(demandId);
                //发送邮件
//                UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, demand.getUserId()));
//                if (Objects.nonNull(userInfo)) {
//                    mailService.sendMail(userInfo.getEmail(), String.format(Constant.DEMAND_BREAK_RULE, userInfo.getEmail()));
//                }
            }
        }
    }


    /**
     * 通知客服拉群
     *
     * @param demand 需求
     */
    private void notifyCustomerOrderTaking(Demand demand) {
        //获取客服ID
        Integer sysUserId = demand.getSysUserId();
        SysUser sysUser = sysUserService.getById(sysUserId);
        if (Objects.nonNull(sysUser)) {
            User user = userService.selectById(demand.getTechUserId());
            if (Objects.nonNull(user)) {
                mailService.sendMail(sysUser.getEmail(), String.format(Constant.DEMAND_ORDER_TAKING, user.getNickname(), demand.getTitle()));
            }
        }
    }


    @Override
    public DemandResponse detail(Integer id) {
        Demand demand = getById(id);
        if (Objects.isNull(demand)) {
            throw new BizException("数据异常");
        }
        return getDemandResponse(demand);
    }

    @Override
    public AppDemandResponse demandDetail(Integer userId, Integer id) {
        Demand demand = baseMapper.selectById(id);
        if (Objects.nonNull(demand)) {
            return getAppDemandResponse(userId, demand);
        }
        return null;
    }

    @Override
    public void updateViewCount(Integer demandId) {
        Demand demand = baseMapper.selectById(demandId);
        if (Objects.isNull(demand)) {
            throw new BizException("该需求已被删除");
        }
        demand.setViewCount(demand.getViewCount() + 1);
        updateById(demand);
    }


    /**
     * APP响应
     *
     * @param demand 需求
     * @return AppDemandResponse
     */
    private AppDemandResponse getListDemandResponse(Integer userId, Demand demand) {
        AppDemandResponse response = new AppDemandResponse();
        BeanUtils.copyProperties(demand, response);
        if (Objects.nonNull(userId)) {
            if (userId.equals(demand.getUserId())) {
                response.setIsMineDemand(true);
            }
        } else {
            //返回空代表用户没有登录
            response.setIsMineDemand(null);
        }
        //需求号码生成规则 W-000001
        response.setDemandNo(Constant.DEMAND_PREFIX + IdWorkUtils.getDemandNo(String.valueOf(demand.getId())));
        if (Objects.nonNull(demand.getHopeFinishTime())) {
            response.setHopeFinishTime(demand.getHopeFinishTime().replace("-", "."));
        }
        response.setPublishTime(DateUtils.getDistanceTime(DateUtils.localDateTime2Date(demand.getCreateTime()),
                new Date()));
        if (StringUtils.isNotEmpty(demand.getImages())) {
            response.setImage(JSONObject.parseArray(demand.getImages(), String.class));
        }
        //设置预算区间
        response.setEstimateAmount(estimateAmountService.getById(demand.getEstimateAmountId()).getPrice());
        response.setTechTypeName(techTypeService.detail(demand.getTechTypeId()).getName());
        return response;
    }


    /**
     * APP响应
     *
     * @param demand 需求
     * @return AppDemandResponse
     */
    private AppDemandResponse getAppDemandResponse(Integer userId, Demand demand) {
        AppDemandResponse response = new AppDemandResponse();
        BeanUtils.copyProperties(demand, response);
        if (Objects.nonNull(userId)) {
            if (userId.equals(demand.getUserId())) {
                response.setIsMineDemand(true);
            }
        } else {
            //返回空代表用户没有登录
            response.setIsMineDemand(null);
        }
        //需求号码生成规则 W-000001
        response.setDemandNo(Constant.DEMAND_PREFIX + IdWorkUtils.getDemandNo(String.valueOf(demand.getId())));
        if (Objects.nonNull(demand.getHopeFinishTime())) {
            response.setHopeFinishTime(demand.getHopeFinishTime());
        }
        response.setPublishTime(DateUtils.getDistanceTime(DateUtils.localDateTime2Date(demand.getCreateTime()),
                new Date()));
        if (StringUtils.isNotEmpty(demand.getImages())) {
            response.setImage(JSONObject.parseArray(demand.getImages(), String.class));
        }
        //设置预算区间
        response.setEstimateAmount(estimateAmountService.getById(demand.getEstimateAmountId()).getPrice());
        response.setTechTypeName(techTypeService.detail(demand.getTechTypeId()).getName());
        return response;
    }

    @Override
    public void updateOrderAmount(Integer demandId, BigDecimal orderAmount) {
        Demand demand = baseMapper.selectById(demandId);
        if (!demand.getStatus().equals(DemandStatusEnum.ALREADY_ORDERED.getCode())) {
            throw new BizException("当前状态还不能设置下单金额");
        }
        //修改该需求的状态为进行中
        demand.setStatus(DemandStatusEnum.PROCESSING.getCode());
        updateById(demand);
        SysConfig sysConfig = sysConfigService.selectByFieldValue(Constant.SETTLED_RATIO);
        if (Objects.isNull(sysConfig)) {
            throw new BizException("请设置技术结算比例");
        }
        BigDecimal techAccount = orderAmount.multiply(new BigDecimal(sysConfig.getFieldValue()));
        //创建需求订单
        demandOrderService.createDemandOrder(orderAmount, techAccount
                , demandId, demand.getUserId(), demand.getTechUserId());

    }

    @Override
    public void updateFinish(Integer demandId) {
        Demand demand = baseMapper.selectById(demandId);
        if (Objects.isNull(demand)) {
            throw new BizException("该需求已被删除");
        }
        demand.setStatus(DemandStatusEnum.FINISH.getCode());
        updateById(demand);
        //修改订单状态 技术为待结算 用户为已完成
        DemandOrder demandOrder = demandOrderService.selectByDemandId(demand.getId());
        if (Objects.isNull(demandOrder)) {
            throw new BizException("该订单有误");
        }
        demandOrder.setUserOrderStatus(UserOrderStatusEnum.FINISH.getCode());
        demandOrder.setTechOrderStatus(TechOrderStatusEnum.TO_BE_SETTLED.getCode());
        demandOrderService.updateById(demandOrder);
        //增加技术的虚拟金额
        userAccountService.increaseBalance(demand.getTechUserId(), demandOrder.getTechAmount());
        UserAccount userAccount = userAccountService.selectUserAccount(demand.getTechUserId());
        //增加技术账户记录
        userAccountRecordService.saveRecord(demand.getTechUserId(), demandOrder.getTechAmount(),
                IncomeTypeEnum.IN.getCode(), AccountTypeEnum.CUSTOMER_MONEY.getCode(), userAccount.getBalance(), null);
        //发送邮件给技术说明钱已经到余额申请提现
        asyncTaskManager.execute(() -> sendTechMoneyToWallet(demand, demandOrder.getTechAmount()));
    }

    @Override
    public void demandOrderCancel(Integer demandId) {
        Demand demand = baseMapper.selectById(demandId);
        if (Objects.isNull(demand)) {
            throw new BizException("该需求已被删除");
        }
        if (!demand.getStatus().equals(DemandStatusEnum.PROCESSING.getCode())) {
            throw new BizException("当前需求不能取消哦");
        }
        demand.setStatus(DemandStatusEnum.VERIFY_PASS.getCode());
        demand.setTechUserId(null);
        updateById(demand);
        //删除记录的接单记录
        demandOrderService.deleteByDemandId(demandId);
    }

    @Override
    public void setTbOrder(Integer demandId, String tbOrderNo) {
        Demand demand = baseMapper.selectById(demandId);
        if (demand.getStatus().equals(DemandStatusEnum.PROCESSING.getCode()) ||
                demand.getStatus().equals(DemandStatusEnum.FINISH.getCode())) {
            demand.setTbOrderNo(tbOrderNo);
            updateById(demand);
        }

    }

    @Override
    public Integer selectUserTakeOrderCount(Integer userId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<Demand>().eq(Demand::getTechUserId, userId));
    }

    /**
     * 发送邮件
     *
     * @param demand     需求
     * @param techAmount 金额
     */
    private void sendTechMoneyToWallet(Demand demand, BigDecimal techAmount) {
        UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, demand.getTechUserId()));
        if (Objects.nonNull(userInfo)) {
            mailService.sendMail(userInfo.getEmail(), String.format(EmailConstant.MONEY_TO_WALLET, userInfo.getEmail(), demand.getTitle(), techAmount.toString()));
        }
    }

    /**
     * 获取需求详情
     *
     * @param demand 需求
     * @return DemandResponse
     */
    private DemandResponse getDemandResponse(Demand demand) {
        DemandResponse response = new DemandResponse();
        BeanUtils.copyProperties(demand, response);
        User user = userService.selectById(demand.getUserId());
        if (Objects.nonNull(user)) {
            response.setAvatar(user.getAvatar());
            response.setUsername(user.getNickname());
            //设置发单人信息
            UserInfoDetailResponse userInfoDetailResponse = userInfoService.detail(user.getId());
            if (Objects.nonNull(userInfoDetailResponse)) {
                if (StringUtils.isNotEmpty(user.getMobile())) {
                    response.setUserMobile(user.getMobile());
                }
                response.setUserQqAccount(userInfoDetailResponse.getQqAccount());
                response.setUserWechatAccount(userInfoDetailResponse.getWechatAccount());

            }
        }
        response.setDemandNo(Constant.DEMAND_PREFIX + IdWorkUtils.getDemandNo(String.valueOf(demand.getId())));
        TechType detail = techTypeService.detail(demand.getTechTypeId());
        if (Objects.nonNull(detail)) {
            response.setTechTypeName(detail.getName());
        }
        if (Objects.nonNull(demand.getHopeFinishTime())) {
            response.setHopeFinishTime(demand.getHopeFinishTime());
        }
        if (StringUtils.isNotEmpty(demand.getImages())) {
            response.setImages(JSONObject.parseArray(demand.getImages(), String.class));
        }
        Integer estimateAmountId = demand.getEstimateAmountId();
        EstimateAmount estimateAmount = estimateAmountService.getById(estimateAmountId);
        if (Objects.nonNull(estimateAmount)) {
            response.setEstimateAmount(estimateAmount.getPrice());
        }
        //查询审核人
        AdminVerifyRecord verifyRecord = adminVerifyRecordService.getOne(new LambdaQueryWrapper<AdminVerifyRecord>().
                eq(AdminVerifyRecord::getDataId, demand.getId()).eq(AdminVerifyRecord::getType, AdminVerifyTypeEnum.DEMAND_VERIFY.getCode()));
        if (Objects.nonNull(verifyRecord)) {
            SysUser sysUser = sysUserService.getById(verifyRecord.getSysUserId());
            response.setVerifyerName(sysUser.getNickname());
        }
        //只有进行中的才展示技术名称
        if (demand.getStatus().equals(DemandStatusEnum.ALREADY_ORDERED.getCode()) ||
                demand.getStatus().equals(DemandStatusEnum.PROCESSING.getCode()) ||
                demand.getStatus().equals(DemandStatusEnum.FINISH.getCode())) {
            User techUser = userService.selectById(demand.getTechUserId());
            if (Objects.nonNull(techUser)) {
                response.setTechUsername(techUser.getNickname());
                //查询技术信息
                UserInfoDetailResponse infoDetailResponse = userInfoService.detail(techUser.getId());
                if (Objects.nonNull(infoDetailResponse)) {
                    response.setTechMobile(infoDetailResponse.getMobile());
                    response.setTechQqAccount(infoDetailResponse.getQqAccount());
                    response.setTechWechatAccount(infoDetailResponse.getWechatAccount());
                }
            }
        }
        if (StringUtils.isNotEmpty(demand.getHopeFinishTime())) {
            response.setHopeFinishTime(demand.getHopeFinishTime());
        }
        //构建需求订单返回对象
        buildDemandOrder(demand, response);
        response.setCreateTime(DateUtils.localDateTime2Date(demand.getCreateTime()));
        return response;
    }

    /**
     * 构建需求订单返回对象
     *
     * @param demand   需求
     * @param response 返回对象
     */
    private void buildDemandOrder(Demand demand, DemandResponse response) {
        List<DemandOrder> orderList = demandOrderService.list(new LambdaQueryWrapper<DemandOrder>().
                eq(DemandOrder::getDemandId, demand.getId()));
        if (!CollectionUtils.isEmpty(orderList)) {
            List<DemandOrderResponse> list = orderList.stream().map(x -> {
                DemandOrderResponse demandOrderResponse = new DemandOrderResponse();
                BeanUtils.copyProperties(x, demandOrderResponse);
                demandOrderResponse.setOrderTime(DateUtils.localDateTime2Date(x.getCreateTime()));
                return demandOrderResponse;
            }).collect(Collectors.toList());
            response.setDemandOrderResponses(list);
        }
    }
}
